#include"network.h"
#include"filesys.h"
#include"cmd_code.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/socket.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<libgen.h>

int clientConn(char* ip_str){
    int servfd = socket(PF_INET,SOCK_STREAM,0);
    if(servfd == -1){
        printf("socket() error!");
        return -1;
    }
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(ip_str);
    serv_addr.sin_port = htons(PORT);

    if(connect(servfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1){
        printf("connect() Error!");
        return -1;
    }
    
    return servfd;
}

int serverInit(){
    int servfd = socket(PF_INET,SOCK_STREAM,0);
    if(servfd == -1){
        printf("socket() 创建失败!");
        return -1;
    }
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(PORT);


    if(bind(servfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1){
        printf("bind() Error!");       
        exit(-1);
    }
    if(listen(servfd,MAX_CONNECTION) == -1){
        printf("listen() Error!");
        return -1;
    }
    return servfd;
}


void networkClose(int sockfd){
    close(sockfd);
}


void mergeData(char *writebuf,int argc, char **argv,char eof){
    int idx = 0;
    for(int i = 0; i < argc; i++){
        int len = strlen(argv[i]);
        memcpy(&writebuf[idx],&len,sizeof(int));
        idx += 4;
        memcpy(&writebuf[idx],argv[i],len);
        idx += len;
    }
    writebuf[idx] = eof;
}


//发送文件
int sendFile(int dstfd, char *src_path){
    int filefd = open(src_path, O_RDWR, 777);
    if(filefd == -1){
        printf("no such file!\n");
        return -1;
    }

    struct stat statbuf;
    fstat(filefd, &statbuf);
    

    char file_name[MAX_FILENAME_SIZE];
    memset(file_name,0,MAX_FILENAME_SIZE);
  
    //获得文件名，文件名长度，文件长度
    int fdata_len = statbuf.st_size;
    strcpy(file_name, basename(src_path));
    int fname_len = strlen(file_name);

    //依次发送文件名长度，文件名，文件长度, 文件内容
    write(dstfd,&fname_len,sizeof(int));
    int wnam_len = write(dstfd,file_name,strlen(file_name));
    write(dstfd,&fdata_len,sizeof(int));
    printf("写入文件名和长度：%d %d\n",wnam_len,fdata_len);

    printf("等待服务器准备\n");
    int status = FSTAT_NOMAL;
    int rstat = read(dstfd,&status,sizeof(int));
    if(rstat == -1 || status == FSTAT_PUT_ERROR){
        printf("发送端发生未知错误\n");
        close(filefd);
        return -1;
    }
    int send_cur = 0; char bit;
    while(send_cur < fdata_len){
        read(filefd,&bit,1);

        int send_cnt = write(dstfd,&bit,1);
        int res = read(dstfd,&status,sizeof(int));
        if(res < 0 || status == FSTAT_PUT_ERROR){
            printf("下载过程中出现错误\n");
            return -1;
            close(filefd);
        }

        send_cur += send_cnt;
        printf("写入:%d 目前:%d\n",send_cur,send_cnt);
    }
    
    printf("文件传输完毕\n");

   
    close(filefd);
    return 0;
}


int recvFile(int srcfd, char *recv_dir){
    int fname_len = 0, fdata_len = 0;
    int status = FSTAT_NOMAL;

    char file_path[DIR_MAX_SIZE];
    memset(file_path,0,DIR_MAX_SIZE);
    char file_name[MAX_FILENAME_SIZE];
    memset(file_name,0,MAX_FILENAME_SIZE);

    //获得文件名长度，文件名和文件长度
    read(srcfd,&fname_len,sizeof(int));
    read(srcfd,file_name,fname_len);
    read(srcfd,&fdata_len,sizeof(int));
    printf("读出文件名长度和数据长度:%d %d\n",fname_len,fdata_len);
    
    strcpy(file_path,recv_dir);
    strcat(file_path,"/");
    strcat(file_path,file_name);

    printf("新文件路径将为:%s\n",file_path);
    
    int filefd = open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 777);
    if(filefd == -1){
        perror("error:");
        status = FSTAT_PUT_ERROR;
        write(srcfd,&status,sizeof(int));
        return -1;
    }
    else{
        write(srcfd,&status,sizeof(int));
    }

    int recv_cur = 0; char bit; 
    while(recv_cur < fdata_len){
        int recv_cnt = read(srcfd,&bit,1);
        if(recv_cnt < 0){
            printf("cilent error!\n");
            status = FSTAT_PUT_ERROR;
            write(srcfd,&status,sizeof(int));
            return -1;
            close(filefd);
        }
        else{
            write(srcfd,&status,sizeof(int));
        }

        write(filefd,&bit,1);
        recv_cur += recv_cnt;
        printf("下载:%d 目前:%d\n",recv_cnt,recv_cur);
    }

    printf("文件下载完毕\n");
    close(filefd);
    return 0;
}













